/*
 * @Author: 0x9DEFA478
 * @Date: 2022-01-20 22:05:44
 * @LastEditTime: 2022-01-25 16:10:05
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "I_Screen.h"
#include "Peripherals_Instence.h"
#include "IP_GPIO.h"
#include "H_ThreadScheduler.h"
#include "MemoryMalloc.h"
#include "System/System.h"

#define I_Screen_Handle_MemoryMalloc                             MemoryMalloc_DTCM
#define I_Screen_Peripheral_MemoryMalloc                         MemoryMalloc_D2SRAM


ST7789_SPI* Screen_ST7789_SPI;
static H_TS_BinarySemaphore* Screen_ST7789_SPI_SpiDoneSemaphore;
static int SPI_Speed;



#define ST7789_SPI_RES_Low()                                     oIP_GPIO_SetOutput_Low(GPIOD,6)
#define ST7789_SPI_RES_High()                                    oIP_GPIO_SetOutput_High(GPIOD,6)

#define ST7789_SPI_DC_Low()                                      oIP_GPIO_SetOutput_Low(GPIOD,5)
#define ST7789_SPI_DC_High()                                     oIP_GPIO_SetOutput_High(GPIOD,5)

#define ST7789_SPI_CS_Low()                                      oIP_GPIO_SetOutput_Low(GPIOA,15)
#define ST7789_SPI_CS_High()                                     oIP_GPIO_SetOutput_High(GPIOA,15)


static void Lock(void* v){
  H_TS_LockLock(ip_spi1_Lock);//锁定互斥锁
}

static void Unlock(void* v){
  H_TS_LockUnlock(ip_spi1_Lock);//释放互斥锁
}

static void Screen_ST7789_SPI_SendDoneCallback(void* v){
  H_TS_BinarySemaphoreGive_ISR(v);
}

static void Reset(void* v){

  ST7789_SPI_CS_High();

  ST7789_SPI_RES_High();
  H_TS_ThreadSleep(100);
  ST7789_SPI_RES_Low();
  H_TS_ThreadSleep(10);
  ST7789_SPI_RES_High();
  H_TS_ThreadSleep(160);

}

static void SPI_Transmit(void* v,void* cmd,int cmdlen,void* dat,int datlen,int speed){

  System_DataMemoryBarrier();//保证缓存写入顺序 如果启用了Cache 还需要缓冲清理操作

  if(speed!=SPI_Speed){
    SPI_Speed=speed;

    if(speed==0){
      IP_SPI_Master_SetSCK_DIV(ip_spi1,0U);
    }else{
      IP_SPI_Master_SetSCK_DIV(ip_spi1,7U);
    }
  }

  IP_SPI_Master_SetBitWidth(ip_spi1,8U);
  IP_SPI_Master_SetCommunicationDoneCallback(ip_spi1,Screen_ST7789_SPI_SendDoneCallback,Screen_ST7789_SPI_SpiDoneSemaphore);
  
  ST7789_SPI_CS_Low();
  
  if((cmd!=NULL)&&(cmdlen!=0)){
    ST7789_SPI_DC_Low();
    IP_SPI_MasterOnlyTx_byteCommunication(ip_spi1,cmd,cmdlen);
    H_TS_BinarySemaphoreTake(Screen_ST7789_SPI_SpiDoneSemaphore);
    while(IP_SPI_Master_IsBusy(ip_spi1)!=0){
    }
  }

  if((dat!=NULL)&&(datlen!=0)){
    ST7789_SPI_DC_High();
    IP_SPI_MasterOnlyTx_byteCommunication(ip_spi1,dat,datlen);
    H_TS_BinarySemaphoreTake(Screen_ST7789_SPI_SpiDoneSemaphore);
    while(IP_SPI_Master_IsBusy(ip_spi1)!=0){
    }
  }

  ST7789_SPI_CS_High();

}

static void SPI_Transmit16Bit(void* v,void* cmd,int cmdlen,void* dat,int datlen,int speed){

  System_DataMemoryBarrier();//保证缓存写入顺序 如果启用了Cache 还需要缓冲清理操作

  if(speed!=SPI_Speed){
    SPI_Speed=speed;

    if(speed==0){
      IP_SPI_Master_SetSCK_DIV(ip_spi1,0U);
    }else{
      IP_SPI_Master_SetSCK_DIV(ip_spi1,7U);
    }
  }

  IP_SPI_Master_SetBitWidth(ip_spi1,16U);
  IP_SPI_Master_SetCommunicationDoneCallback(ip_spi1,Screen_ST7789_SPI_SendDoneCallback,Screen_ST7789_SPI_SpiDoneSemaphore);
  
  ST7789_SPI_CS_Low();
  
  if((cmd!=NULL)&&(cmdlen!=0)){
    ST7789_SPI_DC_Low();
    IP_SPI_MasterOnlyTx_uint16Communication(ip_spi1,cmd,cmdlen);
    H_TS_BinarySemaphoreTake(Screen_ST7789_SPI_SpiDoneSemaphore);
    while(IP_SPI_Master_IsBusy(ip_spi1)!=0){
    }
  }

  if((dat!=NULL)&&(datlen!=0)){
    ST7789_SPI_DC_High();
    IP_SPI_MasterOnlyTx_uint16Communication(ip_spi1,dat,datlen);
    H_TS_BinarySemaphoreTake(Screen_ST7789_SPI_SpiDoneSemaphore);
    while(IP_SPI_Master_IsBusy(ip_spi1)!=0){
    }
  }

  ST7789_SPI_CS_High();

}









/**
 * @brief 设置屏幕亮度
 * @param Light 0~100之间的亮度值
 * @return 无
 */
void I_Screen_SetLight(int Light){

  TIM3->CCR1=Light*8000/100;
}

/**
 * @brief 屏幕初始化
 * @return 无
 */
void I_Screen_ScreenInit(){
  Lock(NULL);
  
  ST7789_ScreenInit(Screen_ST7789_SPI);
  ST7789_SetDirection(Screen_ST7789_SPI,vST7789_SPI_Direction_270);
  ST7789_SetDisplayArea(Screen_ST7789_SPI,0,0,320,240);
  Unlock(NULL);
}

/**
 * @brief 屏幕反初始化
 * @return 无
 */
void I_Screen_ScreenDeInit(){
  ST7789_ScreenDeInit(Screen_ST7789_SPI);
}

/**
 * @brief 初始化屏幕
 * @return 无
 */
void I_Screen_Init(){
  ST7789_SPI_LL_Function LL_Function;
  void* cmdArray;

  SPI_Speed=-1;
  IP_SPI_Master_SetSCK_DIV(ip_spi1,7U);

  LL_Function.v=NULL;
  LL_Function.Lock=Lock;
  LL_Function.Unlock=Unlock;
  LL_Function.Reset=Reset;
  LL_Function.SPI_Transmit=SPI_Transmit;
  LL_Function.SPI_Transmit16Bit=SPI_Transmit16Bit;

  Screen_ST7789_SPI_SpiDoneSemaphore=new_H_TS_BinarySemaphore();

  Screen_ST7789_SPI=I_Screen_Handle_MemoryMalloc.Malloc(sizeof(ST7789_SPI));
  if(Screen_ST7789_SPI==NULL){
    for(;;){
    }
  }

  cmdArray=I_Screen_Peripheral_MemoryMalloc.Malloc(vST7789_SPI_CmdSequenceBufferLength);
  if(cmdArray==NULL){
    for(;;){
    }
  }

  ST7789_SPI_Init(Screen_ST7789_SPI,&LL_Function,cmdArray,0,0,240,320);
}



